import { constants as $const } from '../store/constants'

/**
 * 项目网络状态
 *
 * @param projectId 项目ID
 * @param stateProStatus 项目网络状态数据
 */
export function projectStatus(projectId, stateProStatus) {
  return stateProStatus['networkStatus'] === $const.NETWORK_STATUS_UP
}

/**
 * 环境网络状态
 *
 * @param projectId 项目ID
 * @param envId 环境ID
 * @param stateProStatus 项目网络状态数据
 */
export function envNetStatus(projectId, envId, stateProStatus) {
  let isOk = false
  const envInfos = stateProStatus['envNetStatuses']
  if (!envInfos) {
    return isOk
  }
  for (const envInfoKey in envInfos) {
    const envInfo = envInfos[envInfoKey]
    if (envInfo.envId === envId) {
      isOk = envInfo['networkStatus'] === $const.NETWORK_STATUS_UP
      break
    }
  }
  return isOk
}

/**
 * 组件运行状态，若envId不为空，则返回具体环境中的组件的运行情况，若为空则返回所有环境汇总的情况。
 * <p><b>注：只要有一个环境正常，则总体为正常</b></p>
 *
 * @param projectId 项目ID
 * @param compId 组件ID
 * @param stateProStatus 项目网络状态数据
 * @param envId 环境ID
 */
export function compRunStatus(projectId, compId, stateProStatus, envId) {
  const envInfos = stateProStatus['envNetStatuses']
  if (!envInfos || envInfos.length === 0) {
    return false
  }
  let isCompOK = true

  // envId不为空，则过滤出匹配的环境
  if (envId) {
    const comps = envInfos.find(item => item.envId === envId)['compRunStatuses']
    if (!comps || comps.length === 0) {
      return false
    }
    isCompOK = checkCompStatus(comps, compId)
    return isCompOK
  }

  // envId为空则遍历所有存在当前组件的环境
  for (const envInfoKey in envInfos) {
    const envInfo = envInfos[envInfoKey]
    const comps = envInfo['compRunStatuses']
    if (!comps || comps.length === 0) {
      isCompOK = false
      continue
    }
    isCompOK = checkCompStatus(comps, compId)
    if (isCompOK) {
      // 有一个环境正常就是正常，不再继续检查其他环境，防止干扰
      break
    }
  }
  return isCompOK
}

function checkCompStatus(comps, compId) {
  let isCompOK = true
  let isMatch = false
  for (const compKey in comps) {
    const comp = comps[compKey]
    if (comp['compId'] === compId && comp['runStatus'] === $const.RUN_STATUS_RUNNING) {
      isCompOK = true
      isMatch = true
      break
    }
  }
  // 遍历完没有匹配上说明没有当前组件的数据，则置为false
  if (!isMatch) {
    isCompOK = false
  }
  return isCompOK
}

/**
 * 使用a标签下载模板文件
 *
 * @param templateFileName 模板文件名，默认放在public/static目录下
 */
export function downloadByA(templateFileName) {
  // 通过a标签来实现下载
  const a = document.createElement('a') // 创建一个<a></a>标签
  a.href = '/static/' + templateFileName // 给a标签的href属性值加上地址，注意，这里是绝对路径，不用加点.
  a.download = templateFileName // 设置下载文件文件名，这里加上.docx指定文件类型，pdf文件就指定.pdf即可
  a.style.display = 'none' // 隐藏a标签
  document.body.append('a') // 将a标签追加到document.body中
  a.click() // 模拟点击a标签，会触发a标签的href的读取，浏览器就会自动下载了
  a.remove() // 删除a标签（一次性的）
}

/**
 * 使用a标签从服务器下载文件
 *
 * @param fileName 服务器文件，放在/downloads目录下
 */
export function remoteExportByA(fileName) {
  // 通过a标签来实现下载
  const downloadUrl = process.env.NODE_ENV === 'development' ? process.env.VUE_APP_BASE_API + '/downloads/' + fileName
    : '/downloads/' + fileName
  const a = document.createElement('a')
  a.href = downloadUrl
  a.download = fileName // 下载时显示的文件名
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

// 安全获取深层值，若不存在则返回默认值，且将默认值添加到对象中
export function getDeepDefValue(obj, path, defVal) {
  const deepVal = this.getDeepValue(obj, path)
  if (deepVal === undefined) {
    this.updateDeepValue(obj, path, defVal)
    return defVal
  }
  return deepVal
}

// 安全获取深层值
export function getDeepValue(obj, path) {
  return path.reduce((acc, key) => {
    return acc && acc[key]
  }, obj)
}

// 安全设置深层值（自动创建中间对象）
export function updateDeepValue(obj, path, value) {
  const lastKey = path.pop()
  const target = path.reduce((acc, key) => {
    if (!acc[key]) {
      // Vue2 必须用 $set 确保响应式
      this.$set(acc, key, {})
    }
    return acc[key]
  }, obj)
  this.$set(target, lastKey, value)
}
